import { CCFloat, Component, Node, _decorator } from 'cc';
import { EDITOR } from 'cc/env';
const { ccclass, property } = _decorator;

@ccclass("BaseAction")
export abstract class BaseAction extends Component {
    public static EVENT_VIEW_SHOW = "view_show";
    public static EVENT_VIEW_HIDE = "view_hide";

    @property({ type: CCFloat, tooltip: "动作延时" })
    public delay = 0;
    @property({ type: [Node], tooltip: "后续动作节点列表" })
    public nextActionNodes: Node[] = [];
    @property({ tooltip: "动作所属事件" })
    public event = BaseAction.EVENT_VIEW_SHOW;
    // 后续动作列表。后续动作会在当前动作完成后触发
    private _nextActions: BaseAction[];

    /**
     * 获得后续动作列表
     */
    public get nextActions(): BaseAction[] {
        // 编辑器模式下会自动更新后续动作
        if (EDITOR) {
            this._nextActions = BaseAction.findNextActions(this);
        }

        return this._nextActions;
    }

    public set nextActions(v: BaseAction[]) {
        this._nextActions = v;
    }

    /**
     * 还原属性值(还原到记录的值)
     */
    public abstract recoverProps(): void;

    /**
     * 开始当前动作
     */
    public abstract playAction(callback?: Function, beforeStartAction?: Function): void;

    /**
     * 将属性值修改为动作的初始值
     */
    public abstract setPropToStartValue(): void;

    /**
     * 事件序列播放完成后的回调
     */
    public abstract onEventPlayFinish(): void;

    /**
     * 找出动作的后续动作
     * @param action 
     * @returns 后续动作列表
     */
    public static findNextActions(action: BaseAction): BaseAction[] {
        let nextActions = [];
        for (let node of action.nextActionNodes) {
            for (let comp of node.getComponents("BaseAction")) {
                if (BaseAction.isSameQueue(action, comp as any)) {
                    nextActions.push(comp);
                }
            }
        }

        return nextActions;
    }

    /**
     * 判断是否属于同一个行动队列
     */
    public static isSameQueue(one: BaseAction, other: BaseAction): boolean {
        return one.event == other.event;
    }
}
